﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;

namespace netcore_comm.SqlSugar
{
    public partial class SqlSugarRepository<T, D> : ISqlSugarRepository<T, D> where T : class, new() where D : DataBase
    {
        private ISqlSugarFactory _sqlSugarFactory;

        public DataBase DataBase { get; set; }

        public SqlSugarRepository(ISqlSugarFactory sqlSugarFactory)
        {
            _sqlSugarFactory = sqlSugarFactory;
            DataBase = Activator.CreateInstance(typeof(D)) as DataBase;
        }

        [Obsolete("不能在服务层获取数据库链接")]
        public SqlSugarClient GetNewClient(bool useMainDb = false)
        {
            return _sqlSugarFactory.GetInstance(DataBase.GetName(), useMainDb ? DBOperateType.Write : DBOperateType.Read, DataBase.GetDbType());
        }

        public virtual bool Delete(SqlSugarClient db, T obj)
        {

            var TableClient = new SimpleClient<T>(db);
            return TableClient.Delete(obj);
        }

        public virtual async Task<bool> DeleteAsync(SqlSugarClient db, T obj)
        {

            var TableClient = new SimpleClient<T>(db);
            return await TableClient.DeleteAsync(obj);
        }


        public virtual bool DeleteById(SqlSugarClient db, dynamic id)
        {

            var TableClient = new SimpleClient<T>(db);
            return TableClient.DeleteById(id);
        }

        public virtual async Task<bool> DeleteByIdAsync(SqlSugarClient db, dynamic id)
        {

            var TableClient = new SimpleClient<T>(db);
            return await TableClient.DeleteByIdAsync(id);
        }


        public bool Delete(SqlSugarClient db, Expression<Func<T, bool>> expression)
        {

            var TableClient = new SimpleClient<T>(db);
            return TableClient.Delete(expression);
        }
        public async Task<bool> DeleteAsync(SqlSugarClient db, Expression<Func<T, bool>> expression)
        {

            var TableClient = new SimpleClient<T>(db);
            return await TableClient.DeleteAsync(expression);
        }

        public bool DeleteList(SqlSugarClient db, List<dynamic> ids)
        {

            var TableClient = new SimpleClient<T>(db);
            return TableClient.DeleteByIds(ids.ToArray());
        }
        public async Task<bool> DeleteListAsync(SqlSugarClient db, List<dynamic> ids)
        {

            var TableClient = new SimpleClient<T>(db);
            return await TableClient.DeleteByIdsAsync(ids.ToArray());
        }

        public virtual bool DeleteList(SqlSugarClient db, string ids)
        {
            var list = ids.Split('_');
            var idList = new List<dynamic>();
            foreach (string j in list)
            {
                idList.Add(Convert.ToInt64(j));
            }
            return DeleteList(db, idList);
        }
        public virtual async Task<bool> DeleteListAsync(SqlSugarClient db, string ids)
        {
            var list = ids.Split('_');
            var idList = new List<dynamic>();
            foreach (string j in list)
            {
                idList.Add(Convert.ToInt64(j));
            }
            return await DeleteListAsync(db, idList);
        }

        public virtual bool Exists(SqlSugarClient db, dynamic id)
        {

            return db.Queryable<T>().InSingle(id) != null;
        }
        public virtual async Task<bool> ExistsAsync(SqlSugarClient db, dynamic id)
        {

            return await db.Queryable<T>().InSingleAsync(id) != null;
        }

        public virtual List<T> GetList(SqlSugarClient db)
        {

            var TableClient = new SimpleClient<T>(db);
            return TableClient.GetList();
        }
        public virtual async Task<List<T>> GetListAsync(SqlSugarClient db)
        {

            var TableClient = new SimpleClient<T>(db);
            return await TableClient.GetListAsync();
        }

        public List<T> GetList(SqlSugarClient db, string where)
        {

            return db.Queryable<T>().Where(where).ToList();
        }

        public List<T> GetList(SqlSugarClient db, string where, SugarParameter sugarParameter = null)
        {

            return db.Queryable<T>().Where(where, sugarParameter).ToList();
        }
        public async Task<List<T>> GetListAsync(SqlSugarClient db, string where)
        {

            return await db.Queryable<T>().Where(where).ToListAsync();
        }
        public async Task<List<T>> GetListAsync(SqlSugarClient db, string where, SugarParameter sugarParameter = null)
        {

            return await db.Queryable<T>().Where(where, sugarParameter).ToListAsync();
        }
        public List<T> GetList(SqlSugarClient db, Expression<Func<T, bool>> expression)
        {

            return db.Queryable<T>().Where(expression).ToList();
        }
        public async Task<List<T>> GetListAsync(SqlSugarClient db, Expression<Func<T, bool>> expression, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
        {
            return await db.Queryable<T>().Where(expression).OrderByIF(orderByExpression != null, orderByExpression, orderByType).ToListAsync();
        }
        public async Task<List<T>> GetListAsync(SqlSugarClient db, Expression<Func<T, bool>> expression)
        {
            return await db.Queryable<T>().Where(expression).ToListAsync();
        }

        public virtual T GetModel(SqlSugarClient db, dynamic id)
        {
            var TableClient = new SimpleClient<T>(db);
            return TableClient.GetById(id);
        }
        public virtual async Task<T> GetModelAsync(SqlSugarClient db, dynamic id)
        {

            var TableClient = new SimpleClient<T>(db);
            return await TableClient.GetByIdAsync(id);
        }

        public virtual T GetModel(SqlSugarClient db, Expression<Func<T, bool>> expression)
        {
            T model = null;
            List<T> list = GetList(db, expression);
            if (list.Count > 0) model = list[0];
            return model;
        }

        public virtual async Task<T> GetModelAsync(SqlSugarClient db, Expression<Func<T, bool>> expression)
        {
            T model = null;
            List<T> list = await GetListAsync(db, expression);
            if (list.Count > 0) model = list[0];
            return model;
        }
        public virtual async Task<T> GetModelAsync(SqlSugarClient db, Expression<Func<T, bool>> expression, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
        {
            T model = null;
            List<T> list = await GetListAsync(db, expression, orderByExpression, orderByType);
            if (list.Count > 0) model = list[0];
            return model;
        }

        public virtual List<T> GetPageList(SqlSugarClient db, int pageIndex, int pageSize)
        {

            return db.Queryable<T>()
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();
        }
        public virtual async Task<List<T>> GetPageListAsync(SqlSugarClient db, int pageIndex, int pageSize)
        {

            return await db.Queryable<T>()
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
        }

        public List<T> GetPageList(SqlSugarClient db, int pageIndex, int pageSize, string where)
        {

            return db.Queryable<T>().Where(where)
                 .Skip((pageIndex - 1) * pageSize)
                 .Take(pageSize)
                 .ToList();
        }
        public List<T> GetPageList(SqlSugarClient db, int pageIndex, int pageSize, string where, SugarParameter sugarParameter = null)
        {

            return db.Queryable<T>().Where(where, sugarParameter)
                 .Skip((pageIndex - 1) * pageSize)
                 .Take(pageSize)
                 .ToList();
        }
        public async Task<List<T>> GetPageListAsync(SqlSugarClient db, int pageIndex, int pageSize, string where)
        {

            return await db.Queryable<T>().Where(where)
                 .Skip((pageIndex - 1) * pageSize)
                 .Take(pageSize)
                 .ToListAsync();
        }
        public async Task<List<T>> GetPageListAsync(SqlSugarClient db, int pageIndex, int pageSize, string where, SugarParameter sugarParameter = null)
        {

            return await db.Queryable<T>().Where(where, sugarParameter)
                 .Skip((pageIndex - 1) * pageSize)
                 .Take(pageSize)
                 .ToListAsync();
        }
        public List<T> GetPageList(SqlSugarClient db, int pageIndex, int pageSize, Expression<Func<T, bool>> expression)
        {
            return db.Queryable<T>().Where(expression)
              .Skip((pageIndex - 1) * pageSize)
              .Take(pageSize)
              .ToList();
        }
        public async Task<List<T>> GetPageListAsync(SqlSugarClient db, int pageIndex, int pageSize, Expression<Func<T, bool>> expression)
        {
            return await db.Queryable<T>().Where(expression)
              .Skip((pageIndex - 1) * pageSize)
              .Take(pageSize)
              .ToListAsync();
        }

        public bool Insert(SqlSugarClient db, T obj)
        {
            return db.Insertable(obj).ExecuteCommandIdentityIntoEntity();
        }
        public async Task<bool> InsertAsync(SqlSugarClient db, T obj)
        {
            return await db.Insertable(obj).ExecuteCommandIdentityIntoEntityAsync();
        }

        public bool Update(SqlSugarClient db, T obj)
        {
            var TableClient = new SimpleClient<T>(db);
            return TableClient.Update(obj);
        }
        public async Task<bool> UpdateAsync(SqlSugarClient db, T obj)
        {
            var TableClient = new SimpleClient<T>(db);
            return await TableClient.UpdateAsync(obj);
        }

        public async Task<T> SaveableAsync(SqlSugarClient db, T obj)
        {
            return await db.Saveable(obj).ExecuteReturnEntityAsync();
        }
    }
}
